﻿#include "modelwidget.h"

#include <Qt3DCore/QEntity>
#include <Qt3DRender/QCamera>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DRender/QPointLight>
#include <QVBoxLayout>
#include <QTransform>
#include <QMessageBox>


ModelWidget::ModelWidget(QWidget* parent)
    :QWidget(parent)
{
    this->init3DWindow();
    this->init3DScene();
    this->initConnect();
}


void ModelWidget::parseModelFile(const QString& objFilePath,const QString& mtlFilePath)
{
    // 解析OBJ文件，MTL文件
    if (this->m_modelFileParse.parseModelFile(objFilePath,mtlFilePath)) {
        // 计算得出模型的中心点坐标，使相机初始视角在模型正中心
        QVector3D modelCenter = this->m_modelFileParse.getModelCenter();
        m_camera->setViewCenter(modelCenter);
        m_camera->setPosition(modelCenter + QVector3D(0, 0, 10));
        // 鼠标滚轮缩放速度，与方向
        m_camController->setLinearSpeed(10.0f);
        // 鼠标左键，右键拖动速度
        m_camController->setLookSpeed(-180.0f);

        // 添加每个模型的部件
        for (int i = 0; i < this->m_modelFileParse.m_meshParts.size(); ++i) {
            Qt3DCore::QEntity *partEntity = new Qt3DCore::QEntity(m_rootEntity);

            Qt3DCore::QTransform *transform = new Qt3DCore::QTransform(partEntity);
            transform->setScale(1.0f);
            transform->setTranslation(QVector3D(0, 0, 0));
            partEntity->addComponent(transform);

            // 设置模型
            partEntity->addComponent(this->m_modelFileParse.m_meshParts[i].renderer);
            // 设置材料
            partEntity->addComponent(this->m_modelFileParse.m_meshParts[i].material);
        }
    } else {
        qWarning() << "Failed to parse OBJ file.";
        QMessageBox::warning(nullptr,"错误","模型OBJ文件或材料MTL文件无法打开");
    }
}


void ModelWidget::init3DWindow()
{
    // 创建 QT3D窗口
    m_3dWindow = new Qt3DExtras::Qt3DWindow();

    // 使用 createWindowContainer 将 QWindow 嵌入 QWidget
    m_3dWidget = QWidget::createWindowContainer(m_3dWindow);
    m_3dWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    // 设置焦点策略，以便接收键盘事件
    m_3dWidget->setFocusPolicy(Qt::StrongFocus);

    // 设置布局，将 container 作为唯一子控件
    m_mainVBoxLayout = new QVBoxLayout(this);
    m_mainVBoxLayout->setContentsMargins(0, 0, 0, 0);  // 去除边距
    m_mainVBoxLayout->addWidget(m_3dWidget);
    this->setLayout(m_mainVBoxLayout);
}

void ModelWidget::init3DScene()
{
    // 创建场景根实体
    m_rootEntity = new Qt3DCore::QEntity();
    m_3dWindow->setRootEntity(m_rootEntity);

    // 获取相机
    m_camera = m_3dWindow->camera();
    m_camera->setPosition(QVector3D(0, 0, 10.0f));
    m_camera->setViewCenter(QVector3D(0, 0, 0));
    m_camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);

    // 添加相机控制器
    m_camController = new Qt3DExtras::QOrbitCameraController(m_rootEntity);
    m_camController->setCamera(m_camera);

    // 添加光源
    m_lightEntity = new Qt3DCore::QEntity(m_rootEntity);
    Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(m_lightEntity);
    light->setColor(Qt::white);
    light->setIntensity(1.0f);
    m_lightEntity->addComponent(light);

    Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(m_lightEntity);
    lightTransform->setTranslation(QVector3D(10.0f, 10.0f, 10.0f));
    m_lightEntity->addComponent(lightTransform);
}

void ModelWidget::initConnect(){
    connect(&m_modelFileParse,&ModelFileParse::parseModelFileDoing,this,
            [](int mainProg,int secProg,const QString &message){
        qDebug()<<tr("进度")<< mainProg<<secProg<<message;
    });
}
